第 3 章 深度学习基础
本章介绍了深度学习常见的概念,理解这些概念能够帮助我们从不同角度来更好地优化神经网络。要想更好地优化神经网络,首先,要理解为什么优化会失败,收敛在局部极限值与鞍点会导致优化失败。其次,可以对学习率进行调整,使用自适应学习率和学习率调度。最后,批量归一化可以改变误差表面,这对优化也有帮助。
3.1 局部极小值与鞍点
我们在做优化的时候经常会发现,随着参数不断更新,训练的损失不会再下降, 但是我们对这个损失仍然不满意。把深层网络(deep network)、线性模型和浅层网络(shallow network)做比较,可以发现深层网络没有做得更好——深层网络没有发挥出它完整的力量,所以优化是有问题的。但有时候,模型一开始就训练不起来,不管我们怎么更新参数,损失都降不下去。这个时候到底发生了什么事情?
3.1.1 临界点及其种类
过去常见的一个猜想是我们优化到某个地方,这个地方损失关于参数的微分为零,如图3.1所示。图 3.1 中的两条曲线对应两个神经网络训练的过程。当损失关于参数的微分为零的时候,梯度下降就不能再更新参数了,训练就停下来了,损失不再下降了。
图 3.1 梯度下降失效的情况
提到梯度为零的时候,大家最先想到的可能就是局部极小值(local minimum),如图
但是如果一个点的梯度真的很接近零,我们走到临界点的时候,这个临界点到底是局部极小值还是鞍点,是一个值得去探讨的问题。因为如果损失收敛在局部极小值,我们所在的位置已经是损失最低的点了,往四周走损失都会比较高,就没有路可以走了。但鞍点没有这个问题,旁边还是有路可以让损失更低的。只要逃离鞍点,就有可能让损失更低。
图 3.2 局部极小值与鞍点
3.1.2 判断临界值种类的方法
判断一个临界点到底是局部极小值还是鞍点需要知道损失函数的形状。可是怎么知道损失函数的形状?网络本身很复杂,用复杂网络算出来的损失函数显然也很复杂。虽然无法完整知道整个损失函数的样子,但是如果给定某一组参数,比如
式 (3.1) 是泰勒级数近似(Tayler series appoximation)。其中,第一项
光看
第三项跟海森矩阵(Hessian matrix)
总结一下,损失函数
在临界点,梯度
我们可以根据
(1)如果对所有
(2)如果对所有
(3)如果对于
有一个问题,通过
如果
举个例子,我们有一个简单的神经网络,它只有两个神经元,而且这个神经元还没有激活函数和偏置。输入
我们还有一个简单的训练数据集,这个数据集只有一组数据 (1,1),也就是
图 3.3 简单的神经网络
可以直接画出这个神经网络的误差表面,如图 3.4 所示,可以取
除了尝试取所有可能的损失,我们还有其他的方法,比如把损失的函数写出来。对于图 3.3所示的神经网络,损失函数
图 3.4 误差表面
可以求出损失函数的梯度
什么时候梯度会为零(也就是到一个临界点)呢?比如,在原点时,
海森矩阵
对于原点,只要把
通过海森矩阵来判断原点是局部极小值还是鞍点,要看它的特征值,这个矩阵有两个特征值:2 和
如果我们当前处于鞍点,就不用那么害怕了。
设
若
沿着
在前面的例子中,原点是一个临界点,此时的海森矩阵如式 (3.9) 所示,该海森矩阵有一个负的特征值:−2,特征值 −2 对应的特征向量有无穷多个。不妨取
所以从这个角度来看,鞍点似乎并没有那么可怕。但实际上,我们几乎不会真的把海森矩阵算出来,因为海森矩阵需要算二次微分,计算这个矩阵的运算量非常大,还要把它的特征值跟特征向量找出来,所以几乎没有人用这个方法来逃离鞍点。还有一些其他逃离鞍点的方法的运算量都比要算海森矩阵小很多。
讲到这边会有一个问题:鞍点跟局部极小值谁比较常见?鞍点其实并没有很可怕,如果我们经常遇到的是鞍点,比较少遇到局部极小值,那就太好了。科幻小说《三体 III:死神永生》中有这样一个情节:东罗马帝国的国王君士坦丁十一世为对抗土耳其人,找来了具有神秘力量的做狄奥伦娜。狄奥伦娜可以于万军丛中取上将首级,但大家不相信她有这么厉害,想要狄奥伦娜先展示下她的力量。于是狄奥伦娜拿出了一个圣杯,大家看到圣杯大吃一惊,因为这个圣杯本来是放在圣索菲亚大教堂地下室的一个石棺里面,而且石棺是密封的,没有人可以打开。狄奥伦娜不仅取得了圣杯,还自称在石棺中放了一串葡萄。于是君士坦丁十一世带人撬开了石棺,发现圣杯真的被拿走了,而是棺中真的有一串新鲜的葡萄,为什么迪奥伦娜可以做到这些事呢?是因为狄奥伦娜可以进入四维的空间。从三维的空间来看这个石棺是封闭的,没有任何路可以进去,但从高维的空间来看,这个石棺并不是封闭的,是有路可以进去的。误差表面会不会也一样呢。
如图 3.5(a) 所示的一维空间中的误差表面,有一个局部极小值。但是在二维空间(如图 3.5(b) 所示),这个点就可能只是一个鞍点。常常会有人画类似图 3.5(c) 这样的图来告诉我们深度学习的训练是非常复杂的。如果我们移动某两个参数,误差表面的变化非常的复杂,有非常多局部极小值。低维度空间中的局部极小值点,在更高维的空间中,实际是鞍点。同样地,如果在二维的空间中没有路可以走,会不会在更高维的空间中,其实有路可以走?更高的维度难以视化它,但我们在训练一个网络的时候,参数数量动辄达百万千万级,所以误差表面其实有非常高的维度—— 参数的数量代表了误差表面的维度。既然维度这么高,会不会其实就有非常多的路可以走呢?既然有非常多的路可以走,会不会其实局部极小值就很少呢?而经验上,我们如果自己做一些实验,会发现实际情况也支持这个假说。图 3.6 是训练某不同神经网络的结果,每个点对应一个神经网络。纵轴代表训练网络时,损失收敛到临界点,损失没法下降时的损失。我们常常会遇到两种情况:损失仍然很高,却遇到了临界点而不再下降;或者损失降得很低,才遇到临界点。图3.6中,横轴代表最小值比例(minimumratio),最小值比例定义为
实际上,我们几乎找不到所有特征值都为正的临界点。在图 3.6 所示的例子中,最小值比例最大也不过处于
图 3.5 误差表面
图 3.6 训练不同神经网络的结果
3.2 批量和动量
实际上在计算梯度的时候,并不是对所有数据的损失
随机打乱有很多不同的做法,一个常见的做法是在每一个回合开始之前重新划分批量,也就是说,每个回合的批量的数据都不一样。
图 3.7 使用批量优化
3.2.1 批量大小对梯度下降法的影响
假设现在我们有 20 笔训练数据,先看下两个最极端的情况,如图 3.8 所示。
• 图 3.8 (a)的情况是没有用批量,批量大小为训练数据的大小,这种使用全批量(fullbatch)的数据来更新参数的方法即批量梯度下降法(Batch Gradient Descent,BGD)。此时模型必须把 20 笔训练数据都看完,才能够计算损失和梯度,参数才能够更新一次。
• 图 3.8(b)中,批量大小等于 1,此时使用的方法即随机梯度下降法(Stochastic Gra-dient Descent,SGD),也称为增量梯度下降法。批量大小等于 1 意味着只要取出一笔数据即可计算损失、更新一次参数。如果总共有 20 笔数据,那么在每一个回合里面,参数会更新 20 次。用一笔数据算出来的损失相对带有更多噪声,因此其更新的方向如图 3.8 所示,是曲曲折折的 。
实际上,批量梯度下降并没有“划分批量”:要把所有的数据都看过一遍,才能够更新一次参数,因此其每次迭代的计算量大。但相比随机梯度下降,批量梯度下降每次更新更稳定、更准确。
图 3.8 批量梯度下降法与随机梯度下降法
随机梯度下降的梯度上引入了随机噪声,因此在非凸优化问题中,其相比批量梯度下降更容易逃离局部最小值。
实际上,考虑并行运算,批量梯度下降花费的时间不一定更长;对于比较大的批量,计算损失和梯度花费的时间不一定比使用小批量的计算时间长 。使用 Tesla V100 GPU 在 MNIST数据集得到的实验结果如图 3.9 所示。图 3.9 中横坐标表示批量大小,纵坐标表示给定批量大小的批量,计算梯度并更新参数所耗费的时间。批量大小从 1 到 1000,需要耗费的时间几乎是一样的,因为在实际上 GPU 可以做并行运算,这 1000 笔数据是并行处理的,所以 1000笔数据所花的时间并不是一笔数据的 1000 倍。当然 GPU 并行计算的能力还是存在极限的,当批量大小很大的时候,时间还是会增加的。 当批量大小非常大的时候,GPU 在“跑”完一个批量,计算出梯度所花费的时间还是会随着批量大小的增加而逐渐增长 。当批量大小增加到10000,甚至增加到 60000 的时候,GPU 计算梯度并更新参数所耗费的时间确实随着批量大小的增加而逐渐增长。
MNIST 中的“NIST”是指国家标准和技术研究所(National Institute of Standards andTechnology),其最初收集了这些数据。MNIST 中
图 3.9 批量大小与计算时间的关系
但是因为有并行计算的能力,因此实际上当批量大小小的时候,要“跑”完一个回合,花的时间是比较长的。假设训练数据只有 60000 笔,批量大小设 1,要 60000 个更新才能“跑”完一个回合;如果批量大小等于 1000,60 个更新才能“跑”完一个回合,计算梯度的时间差不多。但 60000 次更新跟 60 次更新比起来,其时间的差距量就非常大了。图 3.10(a) 是用一个批量计算梯度并更新一次参数所需的时间。假设批量大小为 1,“跑”完一个回合,要更新 60000次参数,其时间是非常大的。但假设批量大小是 1000,更新 60 次参数就会“跑”完一个回合。图 3.10(b) 是“跑”完一个完整的回合需要花的时间。如果批量大小为 1000 或 60000,其时间比批量大小设 1 还要短 。图 3.10(a) 和图 3.10(b) 的趋势正好是相反的。因此实际上,在有考虑并行计算的时候,大的批量大小反而是较有效率的,一个回合大的批量花的时间反而是比较少的。
图 3.10 并行计算中批量大小与计算时间的关系
大的批量更新比较稳定,小的批量的梯度的方向是比较有噪声的(noisy)。但实际上有噪声的梯度反而可以帮助训练,如果拿不同的批量来训练模型来做图像识别问题,实验结果如图 3.11 所示,横轴是批量大小,纵轴是正确率。图 3.11(a) 是 MNIST 数据集上的结果,图 3.11(b) 是 CIFAR-10 数据集上的结果。批量大小越大,验证集准确率越差。但这不是过拟合,因为批量大小越大,训练准确率也是越低。因为用的是同一个模型,所以这不是模型偏见的问题。 但大的批量大小往往在训练的时候,结果比较差。这个是优化的问题,大的批量大小优化可能会有问题,小的批量大小优化的结果反而是比较好的。
图 3.11 不同的批量来训练模型来做图像识别问题的实验结果
一个可能的解释如图 3.12 所示,批量梯度下降在更新参数的时候,沿着一个损失函数来更新参数,走到一个局部最小值点或鞍点显然就停下来了。梯度是零,如果不看海森矩阵,梯度下降就无法再更新参数了 。但小批量梯度下降法(mini-batch gradient descent)每次是挑一个批量计算损失,所以每一次更新参数的时候所使用的损失函数是有差异的。选到第一个批量的时候,用
图 3.12 小批量梯度下降更好的原因
其实小的批量也对测试有帮助。假设有一些方法(比如调大的批量的学习率)可以把大的批量跟小的批量训练得一样好。实验结果发现小的批量在测试的时候会是比较好的[1]。在论文“On Large-Batch Training for Deep Learning: Generalization Gap and Sharp Minima”中,作者在不同数据集上训练了六个网络(包括全连接网络、不同的卷积神经网络),在很多不同的情况都观察到一样的结果。在小的批量,一个批量里面有 256 笔样本。在大的批量中,批量大小等于数据集样本数乘 0.1。比如数据集有 60000 笔数据,则一个批量里面有 6000 笔数据。大的批量跟小的批量的训练准确率(accuracy)差不多,但就算是在训练的时候结果差不多,测试的时候,大的批量比小的批量差,代表过拟合。
这篇论文给出了一个解释,如图 3.13 所示,训练损失上面有多个局部最小值,这些局部最小值的损失都很低,其损失可能都趋近于 0。但是局部最小值有好最小值跟坏最小值之分,如果局部最小值在一个“峡谷”里面,它是坏的最小值;如果局部最小值在一个平原上,它是好的最小值。训练的损失跟测试的损失函数是不一样的,这有两种可能。一种可能是本来训练跟测试的分布就不一样;另一种可能是因为训练跟测试都是从采样的数据算出来的,训练跟测试采样到的数据可能不一样,所以它们计算出的损失是有一点差距。 对在一个“盆地”里面的最小值,其在训练跟测试上面的结果不会差太多,只差了一点点。但对在右边在“峡谷”里面的最小值,一差就可以天差地远 。虽然它在训练集上的损失很低,但训练跟测试之间的损失函数不一样,因此测试时,损失函数一变,计算出的损失就变得很大。
大的批量大小会让我们倾向于走到“峡谷”里面,而小的批量大小倾向于让我们走到“盆地”里面。小的批量有很多的损失,其更新方向比较随机,其每次更新的方向都不太一样。即使“峡谷”非常窄,它也可以跳出去,之后如果有一个非常宽的“盆地”,它才会停下来。
大的批量跟小的批量的对比结果如表 3.1 所示。在有并行计算的情况下,小的批量跟大的批量运算的时间并没有太大的差距。除非大的批量非常大,才会显示出差距。但是一个回合需要的时间,小的批量比较长,大的批量反而是比较快的,所以从一个回合需要的时间来看,大的批量是较有优势的。 而小的批量更新的方向比较有噪声的,大的批量更新的方向比较稳定。但是有噪声的更新方向反而在优化的时候有优势,而且在测试的时候也会有优势。所以大的批量跟小的批量各有优缺点,批量大小是需要去调整的超参数。
其实用大的批量大小来做训练,用并行计算的能力来增加训练的效率,并且训练出的结果很好是可以做到的[2-3]。比如 76 分钟训练 BERT[4],15 分钟训练 ResNet[5],一分钟训练ImageNet[6] 等等。这些论文批量大小很大,比如论文“Large Batch Optimization for DeepLearning: Training BERT in 76 minutes ”中批量大小为三万。批量大小很大可以算得很快,这些论文有一些特别的方法来解决批量大小可能会带来的劣势。
图 3.13 小批量优化容易跳出局部最小值的原因
表 3.1 小批量梯度下降与批量梯度下降的比较
评价标准 | 小批量梯度下降 | 批量梯度下降 |
一次更新的速度 (没有并行计算) | 更快 | 更慢 |
一次更新的速度 (有并行计算) | 相同 | 相同 (批量大小不是很大) |
一个回合的时间 | 更慢 | 更快 |
梯度 | 有噪声 | 稳定 |
优化 | 更好 | 更坏 |
泛化 | 更好 | 更坏 |
3.2.2 动量法
动量法(momentum method)是另外一个可以对抗鞍点或局部最小值点的方法。如图 3.14所示,假设误差表面就是真正的斜坡,参数是一个球,把球从斜坡上滚下来,如果使用梯度下降,球走到或鞍点就停住了。 但是在物理的世界里,一个球如果从高处滚下来,就算滚到鞍点或局部最小值点,因为惯性的关系它还是会继续往前走。如果球的动量足够大,其甚至翻过小坡继续往前走。 因此在物理的世界里面,一个球从高处滚下来的时候,它并不一定会被鞍点或局部最小值点卡住,如果将其应用到梯度下降中,这就是动量。
一般的梯度下降(vanilla gradient descent)如图 3.15 所示。初始参数为
引入动量后,每次在移动参数的时候,不是只往梯度的反方向来移动参数,而是根据梯度的反方向加上前一步移动的方向决定移动方向。 图 3.16 中红色虚线方向是梯度的反方向,蓝色虚线方向是前一次更新的方向,蓝色实线的方向是下一步要移动的方向。把前一步指示的方向跟梯度指示的方向相加就是下一步的移动方向。如图 3.16 所示,初始的参数值为
图 3.14 物理世界中的惯性
图 3.15 一般梯度下降
每一步的移动都用
动量的简单例子如图 3.17 所示。红色表示负梯度方向,蓝色虚线表示前一步的方向,蓝色实线表示真实的移动量。一开始没有前一次更新的方向,完全按照梯度给指示往右移动参数。负梯度方向跟前一步移动的方向加起来,得到往右走的方向。一般梯度下降走到一个局部最小值点或鞍点时,就被困住了。但有动量还是有办法继续走下去,因为动量不是只看梯度,还看前一步的方向。即使梯度方向往左走,但如果前一步的影响力比梯度要大,球还是有可能继续往右走,甚至翻过一个小丘,也许可以走到更好的局部最小值,这就是动量有可能带来的好处 。
图 3.16 动量法
图 3.17 动量的好处
3.3 自适应学习率
临界点其实不一定是在训练一个网络的时候会遇到的最大的障碍。图 3.18 中的横坐标代表参数更新的次数,竖坐标表示损失。一般在训练一个网络的时候,损失原来很大,随着参数不断的更新,损失会越来越小,最后就卡住了,损失不再下降。当我们走到临界点的时候,意味着梯度非常小,但损失不再下降的时候,梯度并没有真的变得很小,图 3.19 给出了示例。图 3.19 中横轴是迭代次数,竖轴是梯度的范数(norm),即梯度这个向量的长度。随着迭代次数增多,虽然损失不再下降,但是梯度的范数并没有真的变得很小。
图 3.20 是误差表面,梯度在山谷的两个谷壁间,不断地来回“震荡”,这个时候损失不会再下降,它不是真的卡到了临界点,卡到了鞍点或局部最小值。但它的梯度仍然很大,只是损失不一定再减小了。所以训练一个网络,训练到后来发现损失不再下降的时候,有时候不是卡在局部最小值或鞍点,只是单纯的损失无法再下降。
我们现在训练一个网络,训练到现在参数在临界点附近,再根据特征值的正负号判断该临界点是鞍点还是局部最小值。实际上在训练的时候,要走到鞍点或局部最小值,是一件困难的事情。一般的梯度下降,其实是做不到的。用一般的梯度下降训练,往往会在梯度还很大的时候,损失就已经降了下去,这个是需要特别方法训练的。要走到一个临界点其实是比较困难的,多数时候训练在还没有走到临界点的时候就已经停止了。
图 3.18 训练网络时损失变化
图 3.19 训练网络时梯度范数变化
举个例子,我们有两个参数
学习率
图 3.20 梯度来回“震荡”
图 3.21 凸误差表面
图 3.22 不同的学习率对训练的影响
最原始的梯度下降连简单的误差表面都做不好,因此需要更好的梯度下降的版本。在梯度下降里面,所有的参数都是设同样的学习率,这显然是不够的,应该要为每一个参数定制化学习率,即引入自适应学习率(adaptive learning rate)的方法,给每一个参数不同的学习率。如图 3.23 所示,如果在某一个方向上,梯度的值很小,非常平坦,我们会希望学习率调大一点;如果在某一个方向上非常陡峭,坡度很大,我们会希望学习率可以设得小一点。
3.3.1 AdaGrad
AdaGrad(Adaptive Gradient)是典型的自适应学习率方法,其能够根据梯度大小自动调整学习率。AdaGrad 可以做到梯度比较大的时候,学习率就减小,梯度比较小的时候,学习率就放大。
梯度下降更新某个参数
图 3.23 不同参数需要不同的学习率
现在要有一个随着参数定制化的学习率,即把原来学习率
参数相关的一个常见的类型是算梯度的均方根(root mean square)。参数的更新过程为
其中
其中
第二次更新参数过程为
其中
同样的操作反复继续下去,如式 (3.21) 所示。
第
图 3.24 中有两个参数:
图 3.24 自动调整学习率示例
3.3.2 RMSProp
同一个参数需要的学习率,也会随着时间而改变。在图 3.25 中的误差表面中,如果考虑横轴方向,绿色箭头处坡度比较陡峭,需要较小的学习率,但是走到红色箭头处,坡度变得平坦了起来,需要较大的学习率。因此同一个参数的同个方向,学习率也是需要动态调整的,于是就有了一个新的方法———RMSprop(Root Mean Squared propagation)。
RMSprop 没有论文,Geoffrey Hinton 在 Coursera 上开过深度学习的课程,他在他的课程里面讲了 RMSprop,如果要引用,需要引用对应视频的链接。
RMSprop 第一步跟 Adagrad 的方法是相同的,即
第二步更新过程为
其中
图 3.25 AdaGrad 的问题
的这个梯度的重要性。如果
同样的过程就反复继续下去,如式 (3.25) 所示。
RMSProp 通过
图 3.26 RMSprop 示例
3.3.3 Adam
最常用的优化的策略或者优化器(optimizer)是Adam(Adaptive moment estima-tion)[7]。Adam 可以看作 RMSprop 加上动量,其使用动量作为参数更新方向,并且能够自适应调整学习率。PyTorch 里面已经写好了 Adam 优化器,这个优化器里面有一些超参数需要人为决定,但是往往用 PyTorch 预设的参数就足够好了。
3.4 学习率调度
如图 3.22 所示的简单的误差表面,我们都训练不起来,加上自适应学习率以后,使用AdaGrad 方法优化的结果如图 3.27 所示。一开始优化的时候很顺利,在左转的时候,有 Ada-Grad 以后,可以再继续走下去,走到非常接近终点的位置。走到 BC 段时,因为横轴方向的梯度很小,所以学习率会自动变大,步伐就可以变大,从而不断前进。接下来的问题走到图 3.27中红圈的地方,快走到终点的时候突然“爆炸”了。
图 3.27 AdaGrad 优化的问题
通过学习率调度(learning rate scheduling)可以解决这个问题。之前的学习率调整方法中
除了学习率下降以外,还有另外一个经典的学习率调度的方式— ——预热。预热的方法是让学习率先变大后变小,至于变到多大、变大的速度、变小的速度是超参数。残差网络[8] 里面是有预热的,在残差网络里面,学习率先设置成 0.01,再设置成 0.1,并且其论文还特别说明,一开始用 0.1 反而训练不好。除了残差网络,BERT 和 Transformer 的训练也都使用了预热。
图 3.28 学习率衰减
图 3.29 学习率衰减的优化效果
Q:为什么需要预热?
A:当我们使用 Adam、RMSprop 或 AdaGrad 时,需要计算
3.5 优化总结
所以我们从最原始的梯度下降,进化到这一个版本,如式 (3.27) 所示。
其中
这个版本里面有动量,其不是顺着某个时刻算出的梯度方向来更新参数,而是把过去所有算出梯度的方向做一个加权总和当作更新的方向。接下来的步伐大小为
Q:动量
3.6 分类
分类与回归是深度学习最常见的两种问题,第一章的观看次数预测属于回归问题,本节将介绍分类问题。
3.6.1 分类与回归的关系
回归是输入一个向量
图 3.30 用数字表示类的问题
如果有三个类,标签
如果目标
图 3.31 网络多个输出示例
3.6.2 带有 softmax 的分类
按照上述的设定,分类实际过程是:输入
图 3.32 带有 softmax 的分类
Q:为什么分类过程中要加上 softmax 函数?
A:一个比较简单的解释是,
softmax 的计算如式 (3.28) 所示,先把所有的
其中,
图 3.33 softmax 示例
图 3.33 考虑了三个类的状况,两个类也可以直接套 softmax 函数。但一般有两个类的时候,我们不套 softmax,而是直接取 sigmoid。当只有两个类的时候,sigmoid 和 softmax 是等价的。
3.6.3 分类损失
当我们把
图 3.34 分类损失
计算
但如式 (3.30) 所示的交叉熵更常用,当
接下来从优化的角度来说明相较于均方误差,交叉熵是被更常用在分类上。如图 3.35 所示,有一个三类的分类,网络先输出
图 3.35 使用 softmax 的好处
图 3.36 是分别在
图 3.36 中左上角损失大,右下角损失小,所以期待最后在训练的时候,参数可以“走”到右下角的地方。假设参数优化开始的时候,对应的损失都是左上角。如果选择交叉熵,如图 3.36(a) 所示,左上角圆圈所在的点有斜率的,所以可以通过梯度,一路往右下的地方“走”;如果选均方误差,如图 3.36(b) 所示,左上角圆圈就卡住了,均方误差在这种损失很大的地方,它是非常平坦的,其梯度是非常小趋近于 0 的。如果初始时在圆圈的位置,离目标非常远,其梯度又很小,无法用梯度下降顺利地“走”到右下角。
因此做分类时,选均方误差的时候,如果没有好的优化器,有非常大的可能性会训练不起来。如果用 Adam,虽然图 3.36(b) 中圆圈的梯度很小,但 Adam 会自动调大学习率,还有机会走到右下角,不过训练的过程比较困难。总之,改变损失函数可以改变优化的难度。
图 3.36 均方误差、交叉熵优化对比
3.7 批量归一化
如果误差表面很崎岖,它比较难训练。能不能直接改误差表面的地貌,“把山铲平”,让它变得比较好训练呢?批量归一化(Batch Normalization,BN)就是其中一个“把山铲平”的想法。不要小看优化这个问题,有时候就算误差表面是凸(convex)的,它就是一个碗的形状,都不一定很好训练。如图 3.37 所示,假设两个参数对损失的斜率差别非常大,在
如果是固定的学习率,可能很难得到好的结果,所以我们才需要自适应的学习率、Adam等比较进阶的优化的方法,才能够得到好的结果。从另外一个方向想,直接把难做的误差表面把它改掉,看能不能够改得好做一点。在做这件事之前,第一个要问的问题就是:
图 3.37 训练的问题
图 3.38 是一个非常简单的模型,其输入是
图 3.38 简单的线性模型
什么样的状况会产生像上面这样子,比较不好训练的误差表面呢?对
什么时候
图 3.39 需要特征归一化的原因
以下所讲的方法只是特征归一化的一种可能性,即 Z 值归一化(Z-score normalization),也称为标准化(standardization)。它并不是特征归一化的全部,假设
我们就是把这边的某一个数值
图 3.40 Z 值归一化
归一化有个好处,做完归一化以后,这个维度上面的数值就会平均是 0,其方差是 1,所
以这一排数值的分布就都会在 0 上下;对每一个维度都做一样的归一化,所有特征不同维度的数值都在 0 上下,可能就可以制造一个比较好的误差表面。所以像这样子的特征归一化方式往往对训练有帮助,它可以让在做梯度下降的时候,损失收敛更快一点,训练更顺利一点。
3.7.1 考虑深度学习
虽然
图 3.41 深度学习的归一化
如何对
接下来计算标准差
注意,式 (3.33) 中的平方就是指对每一个元素都去做平方,开根号指的是对向量里面的每一个元素开根号。
最后,根据计算出的
其中,除号代表逐元素的除,即分子分母两个向量对应元素相除。
图 3.42 深度学习中间层的特征归一化
归一化的过程如图 3.42 所示。
如图 3.43 所示,接下来可以通过激活函数得到其他向量,
这是一个较大的网络!
图 3.43 批量归一化可以理解为网络的一部分
在做批量归一化的时候,如图 3.44 所示,往往还会做如下操作:
其中,
Q:为什么要加上
A:如果做归一化以后,
Q:批量归一化是为了要让每一个不同的维度的范围相同,如果把
A:有可能,但是实际上在训练的时候,
图 3.44 加
3.7.2 测试时的批量归一化
以上说的都是训练的部分,测试有时候又称为推断(inference)。批量归一化在测试的时候,会有什么样的问题呢?在测试的时候,我们一次会得到所有的测试数据,确实也可以在测试的数据上面,制造一个一个批量。但是假设系统上线,做一个真正的线上的应用,比如批量大小设 64,我一定要等 64 笔数据都进来,才做一次做运算,这显然是不行的。
但是在做批量归一化的时候,
其中,
图 3.45 测试时的批量归一化
图 3.46 是从批量归一化原始文献的实验结果,横轴代表的是训练的过程,纵轴代表的是验证集上的准确率。黑色的虚线是没有做批量归一化的结果,它用的是 inception 的网络(一种网络以 CNN 为基础的网络架构)。如果有做批量归一化,则是红色的这一条虚线。红色虚线的训练速度显然比黑色的虚线还要快很多。虽然只要给模型足够的训练的时间,最后会收敛都差不多的准确率。但是红色虚线可以在比较短的时间内跑到一样的准确率。蓝色的菱形代表说几个点的准确率是一样的。粉红色的线是 sigmoid 函数,一般的认知,但一般都会选择ReLU,而不是用 sigmoid 函数,因为 sigmoid 函数的训练是比较困难的。但是这边想要强调的点是,就算是 sigmoid 比较难搞的加批量归一化,还是可以训练的,这边没有 sigmoid,没有做批量归一化的结果。因为在这个实验上,sigmoid 不加批量归一化,根本连训练都训练不起来。蓝色的实线跟这个蓝色的虚线呢是把学习率设比较大一点,
图 3.46 批量归一化实验结果[10]
3.7.3 内部协变量偏移
接下来的问题就是批量归一化为什么会有帮助呢?原始的批量归一化论文里面提出内部协变量偏移(internal covariate shift)概念。如图 3.47 所示,假设网络有很多层,
协变量偏移(covariate shift),训练集和预测集样本分布不一致的问题就叫做协变量偏移现象,这个词汇是原来就有的,内部协变量偏移是批量归一化的作者自己发明的。
图 3.47 内部协变量偏移示例
为什么批量归一化会比较好呢,那在这篇“How Does Batch Normalization Help Optimiza-tion?”这篇论文从实验和理论上,至少支持批量归一化可以改变误差表面,让误差表面比较不崎岖这个观点。所以这个观点是有理论的支持,也有实验的佐证的。如果要让网络误差表面变得比较不崎岖,其实不一定要做批量归一化,还有很多其他的方法都可以让误差表面变得不崎岖,这篇论文就试了一些其他的方法,发现跟批量归一化表现也差不多,甚至还稍微好一点,这篇论文的作者也觉得批量归一化是一种偶然的发现,但无论如何,其是一个有用的方法。其实批量归一化不是唯一的归一化,还有很多归一化方法,比如批量重归一化(batchrenormalization)[12]、层归一化(layer normalization)[13]、实例归一化(instance normalization)[14]、组归一化(group normalization)[15]、权重归一化(weight normalization)[16] 和谱归一化(spectrum normalization)[17]。
参考文献
[1] KESKAR N S, MUDIGERE D, NOCEDAL J, et al. On large-batch training for deep learning: Generalization gap and sharp minima[J]. arXiv preprint arXiv:1609.04836, 2016.
[2] GUPTA V, SERRANO S A, DECOSTE D. Stochastic weight averaging in parallel: Large-batch training that generalizes well[J]. arXiv preprint arXiv:2001.02312, 2020.
[3] YOU Y, GITMAN I, GINSBURG B. Large batch training of convolutional networks[J]. arXiv preprint arXiv:1708.03888, 2017.
[4] YOU Y, LI J, REDDI S, et al. Large batch optimization for deep learning: Training bert in 76 minutes[J]. arXiv preprint arXiv:1904.00962, 2019.
[5] AKIBA T, SUZUKI S, FUKUDA K. Extremely large minibatch sgd: Training resnet-50 on imagenet in 15 minutes[J]. arXiv preprint arXiv:1711.04325, 2017.
[6] GOYAL P, DOLLÁR P, GIRSHICK R, et al. Accurate, large minibatch sgd: Training imagenet in 1 hour[J]. arXiv preprint arXiv:1706.02677, 2017.
[7] KINGMA D P, BA J. Adam: A method for stochastic optimization[J]. arXiv preprint arXiv:1412.6980, 2014.
[8] HE K, ZHANG X, REN S, et al. Deep residual learning for image recognition[C]// Proceedings of the IEEE conference on computer vision and pattern recognition. 2016: 770-778.
[9] LIU L, JIANG H, HE P, et al. On the variance of the adaptive learning rate and beyond [J]. arXiv preprint arXiv:1908.03265, 2019.
[10] IOFFE S, SZEGEDY C. Batch normalization: Accelerating deep network training by reducing internal covariate shift[C]//International conference on machine learning. pmlr, 2015: 448-456.
[11] SANTURKAR S, TSIPRAS D, ILYAS A, et al. How does batch normalization help optimization?[J]. Advances in neural information processing systems, 2018, 31.
[12] IOFFE S. Batch renormalization: Towards reducing minibatch dependence in batchnormalized models[J]. Advances in neural information processing systems, 2017, 30.
[13] BA J L, KIROS J R, HINTON G E. Layer normalization[J]. arXiv preprint arXiv:1607.06450, 2016.
[14] ULYANOV D, VEDALDI A, LEMPITSKY V. Instance normalization: The missing ingredient for fast stylization[J]. arXiv preprint arXiv:1607.08022, 2016.
[15] WU Y, HE K. Group normalization[C]//Proceedings of the European conference on computer vision (ECCV). 2018: 3-19.
[16] SALIMANS T, KINGMA D P. Weight normalization: A simple reparameterization to accelerate training of deep neural networks[J]. Advances in neural information processing systems, 2016, 29.
[17] YOSHIDA Y, MIYATO T. Spectral norm regularization for improving the generalizability of deep learning[J]. arXiv preprint arXiv:1705.10941, 2017.